#include "Cal_Size.h"
#include "halconcpp/HalconCpp.h"
#include "qdebug.h"
#include <QDir>
using namespace HalconCpp;
Cal_Size::Cal_Size()
{

}
bool Cal_Size::Read_Txt(int index)
{

    Num_Txt=0;
    QFile file;
    QString CalPath1= QDir::currentPath()+"/Cal/Cal_Cricle/Cricle.txt";
    QString CalPath2= QDir::currentPath()+"/Cal/Cal_Length/Length.txt";
    qDebug()<<CalPath2;
    switch (index) {
    case 1:
        file.setFileName(CalPath1);
        break;
    case 2:
        file.setFileName(CalPath2);
        break;
    default:
        break;

    }
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        while(!file.atEnd())
        {
            QByteArray line = file.readLine();
            QString str(line);
            if(str.toFloat()!=0)
            {
                Real_Size[Num_Txt]=str.toFloat();
                Num_Txt++;
            }
            qDebug()<<Num_Txt;
        }
        return true;
    }
    else
    {
        return false;
    }
    file.close();
}


//玻璃的坐标基本固定不变，就是被测物上表面的高度随着被测物的长度变化而变化
bool Cal_Size::Cal_Length(int direct,float &scale)
{

    HTuple  hv_ImageFiles,Distance;
    HObject Img;
    HObject  Rectangle;
    HObject  ImageReduced, Region, Region1, Region2,ImageReduced1,ImageResult1,ImageResult2,Edges1,Edges2;
    HObject ERegion1,ERegion2,EndPoints1,EndPoints2,JuncPoints1,JuncPoints2,ConnectedRegions1,ConnectedRegions2;



    HTuple  Row, Column, Phi, W, H, r, c;
    HTuple  line1, line2;
    HTuple  MetrologyHandle1, Index1, Line1;
    HTuple  MetrologyHandle2, Line2;

    HTuple  Distance1, Distance2;


    float para17=180;
    float para18=15;
    float para19=3;
    float para20=110;
    float Total=0;

    QString Img_Path= QDir::currentPath()+"/Cal/Cal_Length/Pic";
    try
    {
        ListFiles(Img_Path.toLatin1().data(), (HTuple("files").Append("follow_links")),
                  &hv_ImageFiles);
        TupleRegexpSelect(hv_ImageFiles, (HTuple("\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$").Append("ignore_case")),
                          &hv_ImageFiles);
        if((hv_ImageFiles.TupleLength()>=5)&&(hv_ImageFiles.TupleLength().D()==Num_Txt))
        {
            for(int i=0;i<hv_ImageFiles.TupleLength();i++)
            {
                ReadImage(&Img, HTuple(hv_ImageFiles[i]));


                Threshold(Img, &Region, 0, para17);
                Connection(Region, &Region);
                SelectShape(Region, &Region, (HTuple("area").Append("circularity")),
                            "and", (HTuple(1000).Append(0.3)), (HTuple(99999999).Append(1)));
                Union1(Region, &Region);
                FillUp(Region, &Region);
                SmallestRectangle2(Region, &Row, &Column, &Phi, &W, &H);

                if(direct==1)
                {
                    //垂直
                    GenRectangle2(&Rectangle, Row, Column, Phi, W/2, H+80);
                    ReduceDomain(Img, Rectangle, &ImageReduced);
                    Threshold(ImageReduced, &Region1, 0, para17);
                    Connection (Region1, &Region1);
                    SelectShape(Region1, &Region1, "area", "and", 150, 99999999);
                    Union1(Region1, &Region1);
                    FillUp(Region1, &Region1);
                    ShapeTrans(Region1, &Region1, "rectangle2");
                    DilationRectangle1(Region1, &Region1, para18, para18);
                    PaintRegion(Region1, ImageReduced, &ImageResult1, 0, "fill");
                    EdgesSubPix(ImageResult1, &Edges1, "canny", 3, 20, 40);
                    SelectContoursXld(Edges1, &Edges1, "contour_length", 100, 20000, -0.5,
                                      0.5);
                    GenRegionContourXld(Edges1, &ERegion1, "filled");
                    JunctionsSkeleton(ERegion1, &EndPoints1, &JuncPoints1);
                    Connection(EndPoints1, &ConnectedRegions1);
                    RegionFeatures(ConnectedRegions1, "row", &r);
                    RegionFeatures(ConnectedRegions1, "column", &c);


                }
                else
                {
                    //水平
                    GenRectangle2(&Rectangle, Row, Column, Phi-(PI/2), H/2,
                                  W+80);
                    ReduceDomain(Img, Rectangle, &ImageReduced);
                    Threshold(ImageReduced, &Region2, 0, para17);
                    SelectShape(Region2, &Region2, "area", "and", 150, 99999999);
                    FillUp(Region2, &Region2);
                    ShapeTrans(Region2, &Region2, "rectangle2");
                    DilationRectangle1(Region2, &Region2, para18, para18);
                    PaintRegion(Region2, ImageReduced, &ImageResult2, 0, "fill");
                    EdgesSubPix(ImageResult2, &Edges2, "canny", 3, 20, 40);
                    SelectContoursXld(Edges2, &Edges2, "contour_length", 100, 20000, -0.5,
                                      0.5);
                    GenRegionContourXld(Edges2, &ERegion2, "filled");
                    JunctionsSkeleton(ERegion2, &EndPoints2, &JuncPoints2);
                    Connection(EndPoints2, &ConnectedRegions2);
                    RegionFeatures(ConnectedRegions2, "row", &r);
                    RegionFeatures(ConnectedRegions2, "column", &c);


                }
                line1.Clear();
                line1.Append(HTuple(r[0])).Append(HTuple(c[0])).Append(HTuple(r[1])).Append(HTuple(c[1]));
                line2.Clear();
                line2.Append(HTuple(r[2])).Append(HTuple(c[2])).Append(HTuple(r[3])).Append(HTuple(c[3]));


                //线1
                CreateMetrologyModel(&MetrologyHandle1);
                AddMetrologyObjectLineMeasure(MetrologyHandle1, HTuple(line1[0]), HTuple(line1[1]),
                        HTuple(line1[2]), HTuple(line1[3]), 20, 5, para19, para20, HTuple(),
                        HTuple(), &Index1);
                ApplyMetrologyModel(Img, MetrologyHandle1);
                GetMetrologyObjectResult(MetrologyHandle1, "all", "all", "result_type",
                                         "all_param", &Line1);
                ClearMetrologyModel(MetrologyHandle1);
                //线2
                CreateMetrologyModel(&MetrologyHandle2);
                AddMetrologyObjectLineMeasure(MetrologyHandle2, HTuple(line2[0]), HTuple(line2[1]),
                        HTuple(line2[2]), HTuple(line2[3]), 20, 5, para19, para20, HTuple(),
                        HTuple(), &Index1);
                ApplyMetrologyModel(Img, MetrologyHandle2);
                GetMetrologyObjectResult(MetrologyHandle2, "all", "all", "result_type",
                                         "all_param", &Line2);
                ClearMetrologyModel(MetrologyHandle2);

                //计算边长
                if(Line1.D()!=0&&Line1.D()!=0)
                {
                    DistancePl(HTuple(Line1[0]), HTuple(Line1[1]), HTuple(Line2[0]), HTuple(Line2[1]),
                            HTuple(Line2[2]), HTuple(Line2[3]), &Distance1);
                    DistancePl(HTuple(Line1[2]), HTuple(Line1[3]), HTuple(Line2[0]), HTuple(Line2[1]),
                            HTuple(Line2[2]), HTuple(Line2[3]), &Distance2);

                    Distance = (Distance1+Distance2)/2;

                    Total+=(float)(Real_Size[i]/Distance);

                }
                else
                {
                    return false;
                }

            }
            scale=Total/hv_ImageFiles.TupleLength();
            return true;
        }
        else
        {
            return false;
        }

    }

    catch(HException &exception)
    {
        return false;
    }
}


bool Cal_Size::Cal_Cricle(float &scale)
{
    float Total=0;
    HObject Img,ROI_Img,ROI;
    HObject Region,Contour;
    HTuple Num,Area,Row,Column,Radius;
    HTuple Value,Para,MetrologyHandle,Index;
    HTuple hv_ImageFiles,Parameter,Phi,Length1,Length2,StartPhi,EndPhi,PointOrder;
    QString Img_Path= QDir::currentPath()+"/Cal/Cal_Cricle/Pic";
    try
    {
        ListFiles(Img_Path.toLatin1().data(), (HTuple("files").Append("follow_links")),
                  &hv_ImageFiles);
        TupleRegexpSelect(hv_ImageFiles, (HTuple("\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$").Append("ignore_case")),
                          &hv_ImageFiles);
        if((hv_ImageFiles.TupleLength()>=5)&&(hv_ImageFiles.TupleLength().D()==Num_Txt))
        {
            for(int i=0;i<hv_ImageFiles.TupleLength();i++)
            {
                ReadImage(&Img, HTuple(hv_ImageFiles[i]));
                GenRectangle1(&ROI, 665.421, 796.379, 1425.03, 1732.4);
                ReduceDomain(Img, ROI, &ROI_Img);

                Threshold(ROI_Img, &Region, 0, 128);
                Connection (Region, &Region);
                SelectShape(Region, &Region, (HTuple("area").Append("convexity")),
                            "and", (HTuple(140000).Append(0.8)), (HTuple(500000).Append(1)));
                CountObj(Region,&Num);
                if(Num.D()==1)
                {
                    AreaCenter(Region, &Area, &Row, &Column);
                    RegionFeatures (Region, "width", &Value);
                    Radius = Value/2;
                    Para.Clear();
                    Para.Append(Row).Append(Column).Append(0).Append(Radius).Append(Radius);

                    CreateMetrologyModel(&MetrologyHandle);
                    AddMetrologyObjectGeneric(MetrologyHandle, "ellipse", Para, 70, 5,
                                              1, 30, HTuple(), HTuple(), &Index);
                    ApplyMetrologyModel(ROI_Img, MetrologyHandle);

                    GetMetrologyObjectResult(MetrologyHandle, "all", "all", "result_type",
                                             "all_param", &Parameter);
                    GetMetrologyObjectResultContour(&Contour, MetrologyHandle, "all",
                                                    "all", 1.5);
                    FitEllipseContourXld(Contour, "ftukey", -1, 2, 0, 200, 3, 2, &Row, &Column,
                                         &Phi, &Length1, &Length2, &StartPhi, &EndPhi, &PointOrder);
                    Total += (float)(Real_Size[i]/((Length1+Length2)/2));
                }
                else
                {
                    return false;
                }
            }
            scale=Total/hv_ImageFiles.TupleLength();
            return true;
        }
        else
        {
            return false;
        }
    }
    catch(HException &exception)
    {
        return false;
    }
}


bool Cal_Size::Cal(int index,int direct,float &scale)
{
    switch (index) {
    case 1:
        Flag_R=Read_Txt(1);
        Flag_C=Cal_Cricle(scale);

        break;
    case 2:
        Flag_R=Read_Txt(2);
        Flag_C=Cal_Length(direct,scale);
        break;
    default:
        break;
    }
    Num_Txt=0;
    Flag=(Flag_R&&Flag_C);

    return Flag;
}
